package dao

import (
	"errors"
	"fmt"
	"github.com/liangchao/blogo/src/common/global"
	"github.com/liangchao/blogo/src/common/models"
	"github.com/liangchao/blogo/src/common/utils"
	"strconv"
	"time"
)

type BlogDao struct {
	blogs []models.Blog
}

var (
	blogStatusStr = [2]string{"草稿", "已发布"}
)
var blogs []models.Blog
var blog models.Blog

// NewBlog 添加博客
func (d *BlogDao) NewBlog(blog *models.Blog) (err error) {
	err = blog.CreateBlog()
	if err != nil {
		return
	}
	bc := models.BlogContent{
		BlogId:      blog.BlogId,
		BlogContent: blog.BlogContent,
		CreateTime:  blog.CreateTime,
	}
	err = bc.CreateBlogContent()
	if err != nil {
		return
	}
	r := models.UserBlog{
		BlogId:      blog.BlogId,
		AdminUserId: blog.AuthorID,
		CreateTime:  blog.CreateTime,
	}
	err = r.CreateUserBlog()
	return
}

// UpdateUrlById 更新博客地址通过博客id
func (*BlogDao) UpdateUrlById(blog models.Blog) models.Blog {
	global.DB.Debug().Table(blog.TableName()).Where("blog_id = ?", blog.BlogId).Update("blog_sub_url", blog.BlogSubUrl)
	return blog
}

//func (d *BlogDao) GetBlogListDao(page int, page_size int)  (int, []interface{}){
//
//	blogList := make([]interface{}, 0, len(blogs))
//
//	offset := (page - 1) * page_size
//
//	result := global.DB.Offset(offset).Limit(page_size).Find(&blogs)
//
//	if result.RowsAffected == 0 {
//		return 0, blogList
//	}
//
//	total := len(blogs)
//
//
//	blogList, _ := d.ToMapList()
//
//	return total, blogList
//}

// GetBlogTotal 获得博客的总数
func GetBlogTotal() int {
	var total int64
	result := global.DB.Table("tb_blog").Count(&total)
	if result.RowsAffected == 0 {
		return 0
	}
	return int(total)
}

// GetBlogById 获得博客通过id
func (d *BlogDao) GetBlogById(blogId int) (blog models.Blog, err error) {
	blog.BlogId = blogId
	blog, err = blog.GetBlogById()
	if err != nil {
		return
	}
	err = d.ToMap(&blog)
	return
}

// QueryBlogListByKeyworks 查询博客列表通过关键字（标题，分类，标签）
func (d *BlogDao) QueryBlogListByKeyworks(keywords string, method int, offset int, limit int) (blogs []models.Blog, total int64, err error) {

	switch method {
	case 1:
		{ // 根据 标题查询
			blogs, total, err = blog.GetBlogsByTitleKeywords(keywords, offset, limit)
			// select * from tb_blog where blog_title like '%?%';
		}
	case 2:
		{ // 根据 分类查询
			blogs, total, err = blog.GetBlogsByCategoryKeywords(keywords, offset, limit)
			// select * from tb_blog where blog_category_id in (select category_id from tb_blog_category where category_name like '%G%');
		}
	case 3:
		{ // 根据标签查询
			blogs, total, err = blog.GetBlogsByTagKeywords(keywords, offset, limit)
			// select * from tb_blog where blog_id in (...)
		}
	default:
		err = nil
	}



	if err != nil {
		return nil, 0, err
	}

	for i := 0; i < len(blogs); i++ {
		blogs[i].CreateTimeStr = utils.FormatTime(blogs[i].CreateTime)
	}

	//d.blogs = blogs
	//blogs, err = d.ToMapList()

	return
}

// GetHotBlog 从数据库中获取最热的博客，按照查看人数查找最热
func (d *BlogDao) GetHotBlog(limit int) (blogs []models.Blog, err error) {
	if limit < 1 {
		return nil, errors.New("该查询无意义，limit < 1")
	}
	d.blogs, err = new(models.Blog).GetHotBlog(limit)

	if err != nil {
		return
	}
	if len(d.blogs) > 0 {
		blogs, err = d.ToMapList()
		if err != nil {
			return
		}
	}
	return
}

// GetRecentBlogList 获取最新的博客
func (d *BlogDao) GetRecentBlogList(limit int) (blogs []models.Blog, err error) {
	if limit < 1 {
		return nil, errors.New("该查询无意义，limit < 1")
	}
	blogs, err = new(models.Blog).GetRecentBlogList(limit)

	for i := 0; i < len(blogs); i++ {
		blogs[i].CreateTimeStr = utils.FormatTime(blogs[i].CreateTime)
	}

	//if err != nil {
	//	return
	//}
	//
	//if len(d.blogs) > 0 {
	//	blogs, err = d.ToMapList()
	//	if err != nil {
	//		return nil, err
	//	}
	//}

	return
}

// GetBlogDetailByBid
func (d *BlogDao) GetBlogDetailByBid(bid int) (blogContent models.BlogContent, err error) {
	blogContent.BlogId = bid
	blogContent, err = blogContent.GetBlogContentByBid()
	return

}

// ToMap 转化为想要的输出
func (d *BlogDao) ToMap(blog *models.Blog) (err error) {
	user, _ := new(UserDao).FindUserByBid(blog.BlogId)

	var category models.Category
	if blog.BlogCategoryId > 0 {
		category, err = new(CategoryDao).FindCategoryById(blog.BlogCategoryId)
		if err != nil {
			return
		}
	}

	var tags []models.Tag
	if blog.BlogId > 0 {
		tags, err = new(TagDao).GetTagNamesByBlogId(blog.BlogId)
		if err != nil {
			return
		}
	}

	blog.AuthorName = user.NickName
	blog.BlogCategoryName = category.CategoryName

	for _, tag := range tags {
		blog.BlogTags = append(blog.BlogTags, tag.TagName)
	}
	blog.BlogStatusStr = blogStatusStr[blog.BlogStatus]
	blog.CreateTimeStr = utils.FormatTime(blog.CreateTime)
	blog.UpdateTimeStr = utils.FormatTime(blog.UpdateTime)
	return
}

// ToMapList 转化为想要的输出s
func (d *BlogDao) ToMapList() (blogs []models.Blog, err error) {
	if len(d.blogs) < 1 {
		return
	}
	for _, blog := range d.blogs {
		err = d.ToMap(&blog)
		if err != nil {
			return
		}
		blogs = append(blogs, blog)
	}
	return
}

func AddLikesById(id int) int {
	var likes int = 0
	global.DB.Table("tb_blog").Where("blog_id = ?", id).Select("blog_likes").Find(&likes)

	likes += 1
	global.DB.Table("tb_blog").Where("blog_id = ?", id).Update("blog_likes", likes)
	return likes
}

//func SubLikesById(id int) int {
//	var likes int = 0
//	global.DB.Table("tb_blog").Where("blog_id = ?", id).Select("blog_likes").Find(&likes)
//	if likes <= 0 {
//		return likes
//	}
//	likes -= 1
//	global.DB.Table("tb_blog").Where("blog_id = ?", id).Update("blog_likes", likes)
//	return likes
//}
//
//func AddViewsById(id int) int {
//	var views int = 0
//	global.DB.Table("tb_blog").Where("blog_id = ?", id).Select("blog_views").Find(&views)
//	views += 1
//	global.DB.Table("tb_blog").Where("blog_id = ?", id).Update("blog_views", views)
//	return views
//
//}


// DeleteBlogById 真删除博客通过id
func (d *BlogDao) DeleteBlogById(id int) (err error) {
	err = new(models.Blog).DeleteById(id)
	return
}

// PartitionTable 按照年月分表
func (d *BlogDao) PartitionTable() (calendar [][]models.Blog, err error) {
	oldestBlog, err := new(models.Blog).GetCreateOldestCreateTime()

	if err != nil {
		return
	}

	OldYear, OldMonth := oldestBlog.CreateTime.Year(), oldestBlog.CreateTime.Format("01")
	OldMonthInt, err := strconv.Atoi(OldMonth)
	now := time.Now()
	nowMonthInt, err := strconv.Atoi(now.Format("01"))
	var yearMonths = make([]string, 0)

	if OldYear <= now.Year() {
		// 归档
		for m := OldMonthInt; OldYear < now.Year() && m <= 12; m++ {
			yearMonths = append(yearMonths, fmt.Sprintf("%02d_%02d", OldYear, m))
		}
		for y := OldYear + 1; y < now.Year(); y++ {
			for m := 1; m <= 12; m++ {
				yearMonths = append(yearMonths, fmt.Sprintf("%02d_%02d", y, m))
			}
		}
		for m := 1; OldYear < now.Year() && m <= nowMonthInt; m++ {
			yearMonths = append(yearMonths, fmt.Sprintf("%02d_%02d", now.Year(), m))
		}
		for m := OldMonthInt; OldYear == now.Year() && m <= nowMonthInt; m++ {
			yearMonths = append(yearMonths, fmt.Sprintf("%02d_%02d", now.Year(), m))
		}
	}

	for i := len(yearMonths) - 1; i >= 0; i-- {
		blogs, err = new(models.Blog).GetBlogByYearMonth(yearMonths[i])
		calendar = append(calendar, blogs)
	}

	return
}
